<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:csharp="http://csharp.org" xsi:schemaLocation="urn:oasis:names:tc:emergency:EDXL:HAVE:1.0 edxl-have_pr3.xsd" xmlns:cap="urn:oasis:names:tc:emergency:cap:1.2" xmlns:have="urn:oasis:names:tc:emergency:EDXL:HAVE:1.0" xmlns:de="urn:oasis:names:tc:emergency:EDXL:DE:1.0" xmlns:rmsg="urn:oasis:names:tc:emergency:EDXL:RM:1.0:msg" xmlns:rm="urn:oasis:names:tc:emergency:EDXL:RM:1.0" xmlns:n3="http://www.georss.org/georss" xmlns:gml="http://www.opengis.net/gml" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xal="urn:oasis:names:tc:ciq:xal:3" xmlns:xnl="urn:oasis:names:tc:ciq:xnl:3" xmlns:xpil="urn:oasis:names:tc:ciq:xpil:3">
	<xsl:output method="html" indent="yes" exclude-result-prefixes="msxsl csharp"/>
	<msxsl:script language="CSharp" implements-prefix="csharp"><![CDATA[

	public string gmlEnvelope(string upper, string lower)
	{
		string[] upperCoords=upper.Split(' ');
		string[] lowerCoords =lower.Split(' ');
		
		string A = upperCoords[0]+","+upperCoords[1];
		string B = upperCoords[0]+","+lowerCoords[1];
		string C = lowerCoords[0]+","+lowerCoords[1];
		string D = lowerCoords[0]+","+upperCoords[1];
		
		
		return "http://maps.google.com/maps/api/staticmap?path=fillcolor:0xAA000033|color:0x0000ff|weight:5|"+
			A+"|"+B+"|"+C+"|"+D+"|"+A+
			"&size=512x512&sensor=false";
	}


	public string gmlLineString(string input)
	{
		String[] values = input.Split(' ');
		String points="";
		for (int i=0; i<values.Length; i+=2){ // grab them out in pairs of 2
			points+=values[i]+","+values[i+1];
			if(i<(values.Length-2)){
				points+="|";
			}
		}
		
		return "http://maps.google.com/maps/api/staticmap?path=color:0x0000ff|weight:5|"+points+"&size=512x512&sensor=false";
	}


	public string gmlPolygon(string input)
	{
		String[] values = input.Split(' ');
		string points="";
		for (int i=0; i<values.Length; i+=2){ // grab them out in pairs of 2
			points+=values[i]+","+values[i+1];
			if(i<(values.Length-2)){
				points+="|";
			}
		}
		
		return "http://maps.google.com/maps/api/staticmap?path=fillcolor:0xAA000033|color:0x0000ff|weight:5|"+points+"&size=512x512&sensor=false";
	}

	public string gmlPoint(string input)
	{
		string[] strCoords = input.Split(' ');
				
		double lat = Double.Parse(strCoords[0]);
		double lon =Double.Parse(strCoords[1]);
		return "http://maps.google.com/maps/api/staticmap?zoom=12&size=512x512&markers=color:blue|label:S|"+lat+","+lon+"&sensor=false";
	}
	
	public string gmlCircleByCenterPoint(string position, string strRadius)
	{
		string[] strCoords = position.Split(' ');
		
		double lat = Double.Parse(strCoords[0]);
		double lon =Double.Parse(strCoords[1]);
		double radius = Double.Parse(strRadius);
		
		String points = "";
		for(int deg=0; deg<360; deg+=15){
			points+=calculateDerivedLat(lat, lon, radius, deg);
			points+=",";
			points+=calculateDerivedLon(lat, lon, radius, deg);
			points += "|";
		}
		
		//repeat first point to close the loop
		points+=calculateDerivedLat(lat, lon, radius, 0.0);
		points+=",";
		points+=calculateDerivedLon(lat, lon, radius, 0.0);
		
		return "http://maps.google.com/maps/api/staticmap?path=fillcolor:0xAA000033|color:0x0000ff|weight:5|"+points+"&size=512x512&sensor=false";
	}
	
	
	public const double EarthRadius = 6378137.0;
	
	// from: http://stackoverflow.com/questions/1125144/how-do-i-find-the-lat-long-that-is-x-km-north-of-a-given-lat-long
	/// <summary>
	/// Calculates the end-point from a given source at a given range (meters) and bearing (degrees).
	/// This methods uses simple geometry equations to calculate the end-point.
	/// </summary>
	/// <param name="source">Point of origin</param>
	/// <param name="range">Range in meters</param>
	/// <param name="bearing">Bearing in degrees</param>
	/// <returns>End-point from the source given the desired range and bearing.</returns>
	public static double calculateDerivedLat(double srcLat, double srcLon, double range, double bearing)
	{
		double latA = srcLat * (Math.PI/180.0);
		double lonA = srcLon * (Math.PI/180.0);
		double angularDistance = range / EarthRadius;
		double trueCourse = bearing * (Math.PI/180.0);
	
		double lat = Math.Asin(
			Math.Sin(latA) * Math.Cos(angularDistance) + 
			Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));
	
		return lat * (180.0/Math.PI);
	}




	// from: http://stackoverflow.com/questions/1125144/how-do-i-find-the-lat-long-that-is-x-km-north-of-a-given-lat-long
	/// <summary>
	/// Calculates the end-point from a given source at a given range (meters) and bearing (degrees).
	/// This methods uses simple geometry equations to calculate the end-point.
	/// </summary>
	/// <param name="source">Point of origin</param>
	/// <param name="range">Range in meters</param>
	/// <param name="bearing">Bearing in degrees</param>
	/// <returns>End-point from the source given the desired range and bearing.</returns>
	public static double calculateDerivedLon(double srcLat, double srcLon, double range, double bearing)
	{
		double latA = srcLat * (Math.PI/180.0);
		double lonA = srcLon * (Math.PI/180.0);
		double angularDistance = range / EarthRadius;
		double trueCourse = bearing * (Math.PI/180.0);
	
		double lat = Math.Asin(
			Math.Sin(latA) * Math.Cos(angularDistance) + 
			Math.Cos(latA) * Math.Sin(angularDistance) * Math.Cos(trueCourse));
	
		double dlon = Math.Atan2(
			Math.Sin(trueCourse) * Math.Sin(angularDistance) * Math.Cos(latA), 
			Math.Cos(angularDistance) - Math.Sin(latA) * Math.Sin(lat));
	
		double lon = ((lonA + dlon + Math.PI) % (Math.PI * 2.0)) - Math.PI;
	
		return lon * (180.0/Math.PI);
	}
]]></msxsl:script>



	<xsl:template name="DrawArea" match="*">
		<xsl:if test="gml:Point">
			<xsl:variable name="pos">
				<xsl:value-of select="gml:Point/gml:pos"/>
			</xsl:variable>
			<xsl:value-of select="gml:Point/gml:pos"/>
			<br/>
			<img border="0" alt="Map">
				<xsl:attribute name="src"><xsl:value-of select="csharp:gmlPoint($pos)"/></xsl:attribute>
			</img>
		</xsl:if>
		<xsl:if test="gml:LineString">
					Line String
					<xsl:variable name="coordinates">
				<xsl:value-of select="gml:LineString/gml:posList"/>
			</xsl:variable>
					Coordinates: <xsl:value-of select="gml:LineString/gml:posList"/>
			<br/>
			<img border="0" alt="Map">
				<xsl:attribute name="src"><xsl:value-of select="csharp:gmlLineString($coordinates)"/></xsl:attribute>
			</img>
		</xsl:if>
		<xsl:if test="gml:CircleByCenterPoint">
			<xsl:variable name="pos">
				<xsl:value-of select="gml:CircleByCenterPoint/gml:pos"/>
			</xsl:variable>
			<xsl:variable name="radius">
				<xsl:value-of select="gml:CircleByCenterPoint/gml:radius"/>
			</xsl:variable>
			<img border="0" alt="Map">
				<xsl:attribute name="src"><xsl:value-of select="csharp:gmlCircleByCenterPoint($pos, $radius)"/></xsl:attribute>
			</img>
			<br/>
			Position: <xsl:value-of select="gml:CircleByCenterPoint/gml:pos"/>
			, Radius: <xsl:value-of select="gml:CircleByCenterPoint/gml:radius"/>
		</xsl:if>
		<xsl:if test="gml:Polygon">
				Polygon
				<xsl:variable name="coordinates">
				<xsl:value-of select="gml:Polygon/gml:exterior/gml:LinearRing/gml:posList"/>
			</xsl:variable>
					Coordinates: <xsl:value-of select="gml:Polygon/gml:exterior/gml:LinearRing/gml:posList"/>
			<br/>
			<img border="0" alt="Map">
				<xsl:attribute name="src"><xsl:value-of select="csharp:gmlPolygon($coordinates)"/></xsl:attribute>
			</img>
		</xsl:if>
		<xsl:if test="gml:Envelope">Envelope
					<xsl:variable name="upper">
				<xsl:value-of select="gml:Envelope/gml:upperCorner"/>
			</xsl:variable>
					upper: <xsl:value-of select="gml:Envelope/gml:upperCorner"/>
			<br/>
			<xsl:variable name="lower">
				<xsl:value-of select="gml:Envelope/gml:lowerCorner"/>
			</xsl:variable>
					lower: <xsl:value-of select="gml:Envelope/gml:lowerCorner"/>
			<br/>
			<img border="0" alt="Map">
				<xsl:attribute name="src"><xsl:value-of select="csharp:gmlEnvelope($upper, $lower)"/></xsl:attribute>
			</img>
		</xsl:if>
		<br/>
	</xsl:template>
	
	
	
	


</xsl:stylesheet>
